/*
 * Copyright (C), 2015-2019
 * FileName: LocalVarTab
 * Author:   lizhao
 * Date:     2019-02-12 17:52
 * Description: 局部变量表
 * History:
 * <author>          <time>          <version>          <desc>
 * 作者姓名           修改时间           版本号              描述
 */
package com.lizhaoblog.jjvm.runtime;

import com.lizhaoblog.jjvm.util.ByteUtil;

import java.util.NoSuchElementException;

/**
 * 〈一句话功能简述〉<br>
 * 〈局部变量表〉
 *
 * @author lizhao
 * @date 2019-02-12 17:52
 * @since 1.0.0
 */
public class LocalVarTab {
    private Slot[] localVars;

    public LocalVarTab(int size) {
        localVars = new Slot[size];
        for (int i = 0; i < size; i++) {
            localVars[i] = new Slot();
        }
    }

    public void setInt(int pos, int val) {
        if (pos < 0 || pos >= localVars.length) {
            throw new IllegalArgumentException("invalid index, " + pos);
        }
        localVars[pos].num = val;
    }

    public int getInt(int pos) throws NoSuchElementException {
        if (pos < 0 || pos >= localVars.length) {
            throw new NoSuchElementException();
        }
        return localVars[pos].num;
    }

    public void setFloat(int pos, float val) {
        checkIndex(pos);
        localVars[pos].num = Float.floatToIntBits(val);
    }

    public Float getFloat(int pos) {
        checkIndex(pos);
        return Float.intBitsToFloat(localVars[pos].num);
    }

    public void setLong(int pos, long val) {
        checkIndex(pos + 1);
        int[] ints = ByteUtil.long2IntArr(val);
        localVars[pos].num = ints[0];
        localVars[pos + 1].num = ints[1];
    }

    public long getLong(int pos) {
        checkIndex(pos + 1);
        return ByteUtil.int2Long(localVars[pos].num, localVars[pos + 1].num);
    }

    public void setDouble(int pos, double val) {
        long l = Double.doubleToLongBits(val);
        setLong(pos, l);
    }

    public double getDouble(int pos) {
        long res = getLong(pos);
        return Double.longBitsToDouble(res);
    }

    public void setRef(int pos, JObject ref) {
        checkIndex(pos);
        localVars[pos].ref = ref;
    }

    public JObject getRef(int pos) {
        checkIndex(pos);
        return localVars[pos].ref;
    }

    private void checkIndex(int pos) {
        if (pos < 0 || pos >= size()) {
            throw new IllegalArgumentException("invalid index, " + pos);
        }
    }

    public int size() {
        return localVars.length;
    }


}
